//
//  utils.cpp
//  yuzon
//
//  Created by Alvin on 2023/3/29.
//

#include "utils.hpp"
#include <fstream>

using namespace cv;
using namespace std;

vector<string> LabelList(const string &label_path) {
  vector<string> label_list;
  
  // 基于RAII，不需要file.close()
  ifstream file(label_path);
  string line;
  
  while (getline(file, line)) {
    // 排除空行
    if (line == "")
      continue;
    
    // 删除行末\r
    if (line.find("\r") != string::npos)
      line.erase(line.find("\r"));
    
    label_list.emplace_back(line);
  }
  
  return label_list;
}

vector<vector<float>> AngleList(const string &angle_path) {
  vector<vector<float>> angle_list;
  
  // 基于RAII，不需要file.close()
  ifstream file(angle_path);
  string line;
  
  while (getline(file, line)) {
    // 排除空行
    if (line == "")
      continue;
    
    // 删除行末\r
    if (line.find("\r") != string::npos)
      line.erase(line.find("\r"));
    
    vector<string> row;
    
    stringstream ss(line);
    string word;
    
    while (getline(ss, word, ','))
      row.emplace_back(word);
    
    // 排除首行
    if (row[0] == "name")
      continue;
    
    // 排除列数异常
    if (row.size() != 12)
      continue;
    
    vector<float> angles(11, 0.0f);
    
    // 排除首列
    for (int i = 1; i < row.size(); ++i) {
      // 排除空字符串
      if (row[i] == "")
        break;
      
      angles[i - 1] = stof(row[i]);
    }
    
    angle_list.emplace_back(angles);
  }
  
  return angle_list;
}

vector<Scalar> ColorMap(int64_t num, bool rgb) {
  vector<Scalar> color_map(num);
  int num_colors = (sizeof(kColors) / sizeof(kColors[0])) / 3;
  
  for (int i = 0; i < num; ++i) {
    int index = i;
    
    while (index >= num_colors)
      index -= num_colors;
    
    int r = round(kColors[index * 3] * 255);
    int g = round(kColors[index * 3 + 1] * 255);
    int b = round(kColors[index * 3 + 2] * 255);
    
    color_map[i] = rgb ? Scalar(r, g, b, 255) : Scalar(b, g, r, 255);
  }
  
  return color_map;
}

void Permute(const Mat &image, float *data) {
  int h = image.rows;
  int w = image.cols;
  int c = image.channels();
  
  for (int i = 0; i < c; ++i)
    extractChannel(image, Mat(h, w, CV_32FC1, data + i * h * w), i);
}

int64_t ShapeProduct(const vector<int64_t> &shape) {
  int64_t size = 1;
  for (const int64_t i : shape)
    size *= i;
  return size;
}

bool CompareHumanResult(const HumanResult &a, const HumanResult &b) {
  return a.rect.area() > b.rect.area();
}
